#pragma once

#include "Particles.h"
#include "MovingObject.h"

#include <vector>
using namespace std;

enum emittertypes { point, rectangle, circle, line };
class Emitter
{
private:
#pragma region data members
	//****************************** BOOL ******************************
	// is the emitter looping
	bool isLooping = true;
	// is the emitter attached to something
	bool isAttached = false;

	//****************************** INT ******************************
	// current image number
	int imageID;
	// type of emitter style (point, rectangle, circle, line)
	int emitType;
	// maximum number of particles on the screen
	int maxNumParticles = 100;
	// how many particles are currently active / on the screen
	int activeCount;

	// keep the particles from following the emitter
	int moveDirectionX1;
	int moveDirectionY1;
	int moveDirectionX2;
	int moveDirectionY2;

	// size of the particle image
	int imageSizeX;
	int imageSizeY;

	//****************************** FLOAT ******************************
	// rotation angle for the line emitter type
	float lineRotation;
	// starting rotation angle
	float startRotation = 10;
	// ending rotation angle
	float endRotation;
	// how fast to spawn new particles
	float spawnRate = .01f;
	// timer to keep track of spawn rate
	float spawnTimer;
	// maximum time a particle will live
	float maxParticleAge = 5.0f;

	// I forget what this was for. A timer to keep the particles from following the emitter?
	float moveDirectionXTimer = .2f;
	float moveDirectionYTimer = .2f;

	// emitter max lifetime
	float maxEmitterLife = 4;

	//****************************** POINT ******************************
	// position of the emitter
	SGD::Point position;

	//****************************** SGD::VECTOR ******************************
	// starting velocity
	SGD::Vector startVelocity;
	// ending velocity
	SGD::Vector endVelocity;
	// radius used for the circle emitter type
	SGD::Vector circleVector;
	// radius used for the line emitter type
	SGD::Vector lineVector;

	//****************************** SGD::SCALE ******************************
	// starting scale
	SGD::Size startScale;
	// ending scale
	SGD::Size endScale;

	//****************************** SGD::SIZE ******************************
	// SGD::Size of the rectangle emitter type
	SGD::Size emitterRectSize;

	//****************************** MOVINGOBJECT ******************************
	// owner of the emiiter (usually projectile object)
	GameObject* objectOwner;

	//****************************** SGD::COLOR ******************************
	// starting color
	SGD::Color startColor;
	// ending color
	SGD::Color endColor;

	//****************************** HANDLE ******************************
	// particle image handle
	SGD::HTexture particleImage = SGD::INVALID_HANDLE;

	//****************************** BITMAP ******************************
	// particle image itself (used for save functionality)
	BITMAP image;

	//****************************** STRING ******************************
	// path to the image
	string imagePath;
	// name of the image
	string imageName;

	//****************************** STD::VECTOR ******************************
	// list of particles
	vector<Particles*> particleList;

#pragma endregion

public:
	//****************************** CONSTRUCTORS ******************************
	// default ctor
	Emitter() = default;
	// overloaded ctor
	Emitter(Emitter* savedEmitter);

	//****************************** DECONSTRUCTORS ******************************
	virtual ~Emitter();

	//****************************** FUNCTIONS ******************************
	void Update(float elapsedTime);
	void Render();

	void LoadEmitterXML(string file);
	Particles* Respawn(Particles* who);

#pragma region accessors
	//****************************** ACCESSORS ******************************
	// BOOL 
	bool GetIsLooping() const { return isLooping; }
	bool GetIsAttached() const { return isAttached; }

	// INT 
	int GetImageID() const { return imageID; }
	int GetEmitType() const { return emitType; }
	int GetMaxNumParticles() const { return maxNumParticles; }
	int GetActiveCount() const { return activeCount; }
	int GetMoveDirectionX1() const { return moveDirectionX1; }
	int GetMoveDirectionY1() const { return moveDirectionY1; }
	int GetMoveDirectionX2() const { return moveDirectionX2; }
	int GetMoveDirectionY2() const { return moveDirectionY2; }
	int GetImageSizeX() const { return imageSizeX; }
	int GetImageSizeY() const { return imageSizeY; }

	// FLOAT 
	float GetLineRotation() const { return lineRotation; }
	float GetStartRotation() const { return startRotation; }
	float GetEndRotation() const { return endRotation; }
	float GetSpawnRate() const { return spawnRate; }
	float GetSpawnTimer() const { return spawnTimer; }
	float GetMaxParticleAge() const { return maxParticleAge; }
	float GetMoveDirectionXTimer() const { return moveDirectionXTimer; }
	float GetMoveDirectionYTimer() const { return moveDirectionYTimer; }
	float GetMaxEmitterLife() const { return maxEmitterLife; }

	// POINT 
	SGD::Point GetPosition() const { return position; }

	// SGD::VECTOR 
	SGD::Vector GetStartVelocity() const { return startVelocity; }
	SGD::Vector GetEndVelocity() const { return endVelocity; }
	SGD::Vector GetCircleVector() const { return circleVector; }
	SGD::Vector GetLineVector() const { return lineVector; }

	// SGD::SIZE 
	SGD::Size GetStartScale() const { return startScale; }
	SGD::Size GetEndScale() const { return endScale; }
	SGD::Size GetEmitterRectSize() const { return emitterRectSize; }

	// GAMEOBJECT 
	GameObject* GetObjectOwner() const { return objectOwner; }

	// SGD::COLOR 
	SGD::Color GetStartColor() const { return startColor; }
	SGD::Color GetEndColor() const { return endColor; }

	// HANDLE 
	SGD::HTexture GetParticleImage() const { return particleImage; }

	// BITMAP 
	BITMAP GetImage() const { return image; }

	// STRING 
	string GetImagePath() const { return imagePath; }
	string GetImageName() const { return imageName; }

	// STD::VECTOR 
	vector<Particles*>& GetParticleList() { return particleList; }

#pragma endregion

#pragma region mutators
	//****************************** MUTATORS ******************************
	// BOOL 
	void SetIsLooping(bool loop) { isLooping = loop; }
	void SetIsAttached(bool attached) { isAttached = attached; }

	// INT 
	void SetImageID(int id) { imageID = id; }
	void SetEmitType(int type) { emitType = type; }
	void SetMaxNumParticles(int num) { maxNumParticles = num; }
	void SetActiveCount(int count) { activeCount = count; }
	void SetMoveDirectionX1(int x1) { moveDirectionX1 = x1; }
	void SetMoveDirectionY1(int y1) { moveDirectionY1 = y1; }
	void SetMoveDirectionX2(int x2) { moveDirectionX2 = x2; }
	void SetMoveDirectionY2(int y2) { moveDirectionY2 = y2; }
	void SetImageSizeX(int x) { imageSizeX = x; }
	void SetImageSizeY(int y) { imageSizeY = y; }

	// FLOAT 
	void SetLineRotation(float rot) { lineRotation = rot; }
	void SetStartRotation(float rot) { startRotation = rot; }
	void SetEndRotation(float rot) { endRotation = rot; }
	void SetSpawnRate(float rate) { spawnRate = rate; }
	void SetSpawnTimer(float timer) { spawnTimer = timer; }
	void SetMaxParticleAge(float age) { maxParticleAge = age; }
	void SetMoveDirectionXTimer(float timer) { moveDirectionXTimer = timer; }
	void SetMoveDirectionYTimer(float timer) { moveDirectionYTimer = timer; }
	void SetMaxEmitterLife(float life) { maxEmitterLife = life; }

	// POINT 
	void SetPosition(SGD::Point pos) { position = pos; }

	// SGD::VECTOR 
	void SetStartVelocity(SGD::Vector vel) { startVelocity = vel; }
	void SetEndVelocity(SGD::Vector vel) { endVelocity = vel; }
	void SetCircleVector(SGD::Vector circle) { circleVector = circle; }
	void SetLineVector(SGD::Vector line) { lineVector = line; }

	// SGD::SIZE 
	void SetStartScale(SGD::Size scale) { startScale = scale; }
	void SetEndScale(SGD::Size scale) { endScale = scale; }
	void SetEmitterRectSize(SGD::Size size) { emitterRectSize = size; }

	// MOVINGOBJECT 
	void SetObjectOwner(GameObject* owner) { objectOwner = owner; }

	// SGD::COLOR 
	void SetStartColor(SGD::Color color) { startColor = color; }
	void SetEndColor(SGD::Color color) { endColor = color; }

	// HANDLE 
	void SetParticleImage(SGD::HTexture image) { particleImage = image; }

	// BITMAP 
	void SetImage(BITMAP image) { this->image = image; }

	// STRING 
	void SetImagePath(string path) { imagePath = path; }
	void SetImageName(string name) { imageName = name; }

	// STD::VECTOR 
	void SetParticleList(vector<Particles*> list) { particleList = list; }
#pragma endregion

};